package com.uinnova.product.eam.service.impl;

import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.binary.core.exception.BinaryException;
import com.binary.jdbc.Page;
import com.uinnova.product.eam.comm.model.es.AppSquareConfig;
import com.uinnova.product.eam.comm.model.es.AssetWarehouseDir;
import com.uinnova.product.eam.comm.model.es.EamCategory;
import com.uinnova.product.eam.model.AppSquareConfigBo;
import com.uinnova.product.eam.model.cj.domain.PlanDesignShareRecord;
import com.uinnova.product.eam.model.constants.GlobalSearchLocationType;
import com.uinnova.product.eam.model.dto.EamCategoryDTO;
import com.uinnova.product.eam.model.enums.CategoryTypeEnum;
import com.uinnova.product.eam.model.vo.GlobalSearchCategoryFillParam;
import com.uinnova.product.eam.model.vo.GlobalSearchQueryVo;
import com.uinnova.product.eam.model.vo.GlobalSearchResDirVo;
import com.uinnova.product.eam.model.vo.GlobalSearchResVo;
import com.uinnova.product.eam.service.AppSquareConfigSvc;
import com.uinnova.product.eam.service.AssetWarehouseDirSvc;
import com.uinnova.product.eam.service.EamCategorySvc;
import com.uinnova.product.eam.service.IGlobalSearchService;
import com.uinnova.product.eam.service.cj.dao.PlanDesignShareRecordDao;
import com.uinnova.product.eam.service.es.IamsESCIDesignSvc;
import com.uinnova.product.eam.service.es.IamsESCIPrivateSvc;
import com.uinnova.product.eam.service.es.IamsESCmdbCommDesignSvc;
import com.uinnova.product.vmdb.comm.model.ci.CcCiAttrDef;
import com.uinnova.project.base.diagram.comm.diagram.DiagramShareRecord;
import com.uinnova.project.service.eam.IEamShareDiagramSvc;
import com.uino.api.client.permission.IUserApiSvc;
import com.uino.bean.cmdb.base.ESCIClassInfo;
import com.uino.bean.cmdb.base.ESCIInfo;
import com.uino.bean.cmdb.base.LibType;
import com.uino.bean.cmdb.query.ESAttrBean;
import com.uino.bean.cmdb.query.ESCISearchBean;
import com.uino.bean.permission.base.SysModule;
import com.uino.bean.permission.base.SysRole;
import com.uino.bean.permission.base.SysUser;
import com.uino.bean.permission.business.UserInfo;
import com.uino.bean.permission.query.CSysUser;
import com.uino.dao.AbstractESBaseDao;
import com.uino.dao.BaseConst;
import com.uino.dao.cmdb.ESCIClassSvc;
import com.uino.dao.permission.ESModuleSvc;
import com.uino.util.sys.SysUtil;
import lombok.extern.log4j.Log4j2;
import org.apache.commons.lang.StringUtils;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.BoolQueryBuilder;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.sort.SortBuilder;
import org.elasticsearch.search.sort.SortBuilders;
import org.elasticsearch.search.sort.SortOrder;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Lazy;
import org.springframework.stereotype.Service;
import org.springframework.util.CollectionUtils;

import javax.annotation.Resource;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.stream.Collectors;

@Service
@Log4j2
public class GlobalSearchSvcImpl extends AbstractESBaseDao<Object, Object> implements IGlobalSearchService {

    @Resource
    AssetWarehouseDirSvc assetWarehouseDirSvc;

    @Override
    public String getIndex() {
        return null;
    }

    @Override
    public String getType() {
        return null;
    }

    private static final String TYPE_PLAN = "plan";
    private static final String TYPE_DIAGRAM = "diagram";
    private static final String TYPE_ASSET = "asset";
    private static final String TYPE_MODEL = "model";
    private static final String ES_INDEX_DIAGRAM = "uino_monet_diagram";
    private static final String ES_TYPE_DIAGRAM = "_doc";
    private static final String ES_INDEX_PLAN = "uino_cj_plan_design_instance";
    private static final String ES_TYPE_PLAN = "uino_cj_plan_design_instance";
    private static final String ES_INDEX_CI_PRIVATE = "uino_cmdb_ci_private";
    private static final String ES_TYPE_CI_PRIVATE = "uino_cmdb_ci_private";
    private static final String ES_INDEX_CI_DESIGN = "uino_cmdb_ci_design";
    private static final String ES_TYPE_CI_DESIGN = "uino_cmdb_ci_design";
    private static final String ES_INDEX_MODEL_PRIVATE = "uino_eam_category_private";
    private static final String ES_TYPE_MODEL_PRIVATE = "uino_eam_category_private";
    private static final String ES_INDEX_MODEL_DESIGN = "uino_eam_category_design";
    private static final String ES_TYPE_MODEL_DESIGN = "uino_eam_category_design";
    private static final String IS_OPEN = "isOpen";
    private static final String DIRID = "dirId";
    private static final String STATUS = "status";
    private static final String ASSETS_TYPE = "assetsType";
    private static final String DOMAIN_ID_STRING = "domainId";
    private static final String MY_DESIGN_ROUTE_KEYS = "framework-design";
    private static final String DESIGN_LIBRARY_MODULE_SIGN = "设计资产管理";
    /**
     * <p>状态</p>
     * <p>deleted：已删除</p>
     * <p>published：已发布</p>
     * <p>draft：草稿</p>
     * <p>history：历史版本</p>
     */
    private static final Map<String, String> PLAN_STATUS;
    static {
        PLAN_STATUS = new ConcurrentHashMap<>();
        PLAN_STATUS.put("deleted", "已删除");
        PLAN_STATUS.put("published", "已发布");
        PLAN_STATUS.put("draft", "草稿");
        PLAN_STATUS.put("history", "历史版本");
    }
    @Value("${data.scope:}")
    private String dataScope;
    @Resource
    private RestHighLevelClient client;
    @Value("${bufferLimitBytes:524288000}")
    private String bufferLimitBytes;
    @Autowired
    private IEamShareDiagramSvc shareDiagramSvc;
    @Autowired
    private IUserApiSvc userApiSvc;
    @Autowired
    private ESModuleSvc esModuleSvc;
    @Autowired
    private EamCategorySvc eamCategorySvc;
    @Autowired
    private PlanDesignShareRecordDao planDesignShareRecordDao;
    @Autowired
    private AppSquareConfigSvc basicOperationSettingSvc;
    @Autowired
    @Lazy
    private IamsESCmdbCommDesignSvc commSvc;
    @Autowired
    @Lazy
    private ESCIClassSvc classSvc;
    @Autowired
    private IamsESCIDesignSvc esciDesignSvc;
    @Autowired
    private IamsESCIPrivateSvc esciPrivateSvc;

    public Page<GlobalSearchResVo> search(GlobalSearchQueryVo params) {
        if (StringUtils.isBlank(params.getKeyword())
                || CollectionUtils.isEmpty(params.getTypes())
                || CollectionUtils.isEmpty(params.getLocationTypes())) {
            return new Page<>(params.getPageNum(), params.getPageSize(), 0L,0L, null);
        }
        if (params.getPageSize() > 30) {
            params.setPageSize(30);
        }
        List<String> esIndices = new ArrayList<>();
        List<String> esTypes = new ArrayList<>();
        setEsIndicesAndType(params, esIndices, esTypes);
        List<GlobalSearchResVo> datas = new ArrayList<>();
        List<SortBuilder<?>> sorts = new ArrayList<>();
        //modifyTime
        sorts.add(SortBuilders.fieldSort("modifyTime").order(SortOrder.DESC));
        //createTime
        sorts.add(SortBuilders.fieldSort("createTime").order(SortOrder.DESC));
        BoolQueryBuilder queryBuilder = this.getQueryBuilder(params);
        Page<SearchHit> page = this.muiltyIndexQuery(esIndices.toArray(new String[esIndices.size()]),
                esTypes.toArray(new String[0]), queryBuilder, params.getPageNum(), params.getPageSize(), sorts);
        if (!CollectionUtils.isEmpty(page.getData())) {
            for (SearchHit hit : page.getData()) {
                datas.add(this.getResultWapper(hit));
            }
        }
        //包装返回结果
        this.warpeDatas(datas, params);
        return this.resultTransPage(params.getPageNum(), params.getPageSize(), page.getTotalRows(), datas);
    }

    private void setEsIndicesAndType(GlobalSearchQueryVo params, List<String> esIndices, List<String> esTypes) {
        //查询位置只有"资产管理"，那么只能查资产
        if (params.getLocationTypes().size() == 1 &&
                params.getLocationTypes().contains(GlobalSearchLocationType.ASSET_MANAGE)) {
            esIndices.addAll(getAssetEsIndex());
            esTypes.addAll(getAssetEsType());
            return;
        }
        if (params.getTypes().contains(TYPE_PLAN)) {
            esIndices.add(getPlanEsIndex());
            esTypes.add(getPlanEsType());
        }
        if (params.getTypes().contains(TYPE_DIAGRAM)) {
            esIndices.add(getDiagramEsIndex());
            esTypes.add(getDiagramEsType());
        }
        if (params.getTypes().contains(TYPE_ASSET)) {
            esIndices.addAll(getAssetEsIndex());
            esTypes.addAll(getAssetEsType());
        }
        if (params.getTypes().contains(TYPE_MODEL)) {
            esIndices.addAll(getModelEsIndex(params.getLocationTypes()));
            esTypes.addAll(getModelEsType(params.getLocationTypes()));
        }
    }

    private GlobalSearchResVo getResultWapper(SearchHit hit) {
        String recordStr = hit.getSourceAsString();
        JSONObject source = JSON.parseObject(recordStr);
        GlobalSearchResVo res = new GlobalSearchResVo();
        String index = this.unWarpIndex(hit.getIndex());
        switch (hit.getIndex()) {
            case ES_INDEX_PLAN:
                this.planResultWapper(res, source);
                break;
            case ES_INDEX_DIAGRAM:
                this.diagramResultWapper(res, source);
                break;
            case ES_INDEX_MODEL_PRIVATE:
                this.modelResultWapper(res, source, LibType.PRIVATE);
                break;
            case ES_INDEX_MODEL_DESIGN:
                this.modelResultWapper(res, source, LibType.DESIGN);
                break;
            case ES_INDEX_CI_PRIVATE:
                this.assetResultWapper(res, source, LibType.PRIVATE);
                break;
            case ES_INDEX_CI_DESIGN:
                this.assetResultWapper(res, source, LibType.DESIGN);
                break;
            default:
                throw new BinaryException("未知的索引[" + index + "]");
        }
        return res;
    }

    private void planResultWapper(GlobalSearchResVo res, JSONObject source) {
        res.setType(TYPE_PLAN);
        res.setStatus(source.getString(STATUS) == null ? "-" :
                PLAN_STATUS.getOrDefault(source.getString(STATUS), "-"));
        res.setId(source.getLong("id"));
        res.setLibType(source.getInteger(ASSETS_TYPE) == 1 ? LibType.PRIVATE : LibType.DESIGN);
        res.setDirId(source.getInteger(ASSETS_TYPE) == 1 ? source.getLong(DIRID) : source.getLong("assetsDirId"));
        res.setName(source.getString("name"));
        res.setAssetsType(source.getInteger(ASSETS_TYPE));
        res.setCreatorName(source.getString("creatorName"));
        res.setCreator(source.getString("creatorCode"));
        res.setCreateTime(this.transDateFormat(source.getString("createTime")));
        res.setModifyTime(this.transDateFormat(source.getString("modifyTime")));
    }

    private void diagramResultWapper(GlobalSearchResVo res, JSONObject source) {
        res.setType(TYPE_DIAGRAM);
        res.setId(source.getLong("id"));
        res.setDirId(source.getLong(DIRID));
        res.setName(source.getString("name"));
        res.setViewType(source.getString("viewType"));
        res.setdEnergy(source.getString("dEnergy"));
        res.setIsOpen(source.getInteger(IS_OPEN));
        res.setLibType(source.getInteger(IS_OPEN) == 0 ? LibType.PRIVATE : LibType.DESIGN);
        String status = "-";
        if (source.getInteger(IS_OPEN) == 0) {
            status = StringUtils.isBlank(source.getString("releaseDiagramId")) ? "草稿" : "已发布";
        }
        res.setStatus(status);
        res.setCreatorName(source.getString("creatorName"));
        res.setCreator(source.getString("creator"));
        res.setCreateTime(this.transDateFormat(source.getString("createTime")));
        res.setModifyTime(this.transDateFormat(source.getString("modifyTime")));
    }

    private void modelResultWapper(GlobalSearchResVo res, JSONObject source, LibType libType) {
        res.setType(TYPE_MODEL);
        res.setStatus("-");
        res.setId(source.getLong("id"));
        res.setDirId(source.getLong("id"));
        res.setName(source.getString("dirName"));
        res.setLibType(libType);
        res.setCreator(source.getString("creator"));
        res.setCreateTime(this.transDateFormat(source.getString("createTime")));
        res.setModifyTime(this.transDateFormat(source.getString("modifyTime")));
    }

    private void assetResultWapper(GlobalSearchResVo res, JSONObject source, LibType libType) {
        res.setType(TYPE_ASSET);
        res.setId(source.getLong("id"));
        res.setClassId(source.getLong("classId"));
        res.setCiCode(source.getString("ciCode"));
        res.setLibType(libType);
        res.setCreator(libType.equals(LibType.PRIVATE) ? source.getString("ownerCode") : source.getString("creator"));
        res.setCreateTime(this.transDateFormat(source.getString("createTime")));
        res.setModifyTime(this.transDateFormat(source.getString("modifyTime")));
        res.setCiInfo(source.toJavaObject(ESCIInfo.class));
    }

    /**
     * 包装返回结果
     * @param datas
     */
    private void warpeDatas(List<GlobalSearchResVo> datas, GlobalSearchQueryVo params) {
        if (CollectionUtils.isEmpty(datas)) {
            return;
        }
        GlobalSearchCategoryFillParam fillParam = this.fillCategoryPrepare(datas, params);
        //数据拼装
        for (GlobalSearchResVo data : datas) {
            if (StringUtils.isNotBlank(data.getCreator())) {
                data.setCreatorName(fillParam.getUserInfoMap().getOrDefault(data.getCreator(), new SysUser()).getUserName());
            }
            this.fillCategory(data, fillParam);
            this.fillAssetInfo(data, fillParam);
        }
    }

    private GlobalSearchCategoryFillParam fillCategoryPrepare(List<GlobalSearchResVo> datas, GlobalSearchQueryVo params) {
        //私有库资产目录
        List<Long> privateDirIds = datas.stream()
                .filter(data -> !data.getType().equals(TYPE_ASSET))
                .filter(data -> data.getLibType().equals(LibType.PRIVATE))
                .filter(data -> data.getDirId() != null)
                .map(GlobalSearchResVo::getDirId)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, EamCategory> privateCategoryMap = this.getCategoryMapByDirIds(privateDirIds, LibType.PRIVATE);

        //资产库资产目录
        List<Long> designCategoryIds = datas.stream()
                .filter(data -> !data.getType().equals(TYPE_ASSET))
                .filter(data -> data.getLibType().equals(LibType.DESIGN))
                .filter(data -> data.getDirId() != null)
                .map(GlobalSearchResVo::getDirId)
                .distinct()
                .collect(Collectors.toList());
        Map<Long, EamCategory> designCategoryMap = this.getCategoryMapByDirIds(designCategoryIds, LibType.DESIGN);

        //用户数据
        Map<String, SysUser> userInfoMap = new ConcurrentHashMap<>();
        List<String> loginCodes = datas.stream()
                .filter(data -> StringUtils.isNotBlank(data.getCreator()))
                .map(GlobalSearchResVo::getCreator).distinct().collect(Collectors.toList());
        if (!CollectionUtils.isEmpty(loginCodes)) {
            CSysUser userParms = new CSysUser();
            userParms.setLoginCodes(loginCodes.toArray(new String[0]));
            List<SysUser> users = userApiSvc.getSysUserByCdt(userParms);
            userInfoMap = users.stream().collect(Collectors.toMap(SysUser::getLoginCode, e -> e));
        }

        //资产仓库菜单
        SysModule designModule = new SysModule();
        //获取顶级目录对应菜单位置
        Map<Long, List<AssetWarehouseDir>> libraryModuleMap = new ConcurrentHashMap<>();
        if (params.getLocationTypes().contains(GlobalSearchLocationType.DESIGN)) {
            UserInfo user = userApiSvc.getUserInfoById(SysUtil.getCurrentUserInfo().getId());
            List<SysModule> sysModuleList = esModuleSvc.getListByRoleIds(user.getRoles().stream().map(SysRole::getId).collect(Collectors.toList()));
            List<AssetWarehouseDir> sysModules = assetWarehouseDirSvc.getListByRoleIds(user.getRoles().stream().map(SysRole::getId).collect(Collectors.toList()));

            libraryModuleMap = this.libraryModuleMap(sysModules);
            List<SysModule> designModules = sysModuleList.stream().filter(sysModule ->
                    DESIGN_LIBRARY_MODULE_SIGN.equals(sysModule.getModuleSign())).collect(Collectors.toList());
            if (!CollectionUtils.isEmpty(designModules)) {
                designModule = designModules.get(0);
            }
        }

        //分享视图
        List<Long> shareDiagramIds = new ArrayList<>();
        //分享方案
        List<Long> sharePlanIds = new ArrayList<>();
        //"架构设计"才会有分享
        if (params.getLocationTypes().contains(GlobalSearchLocationType.PRIVATE)) {
            if (params.getTypes().contains(TYPE_PLAN)) {
                sharePlanIds = this.getSharePlanIds();
            }
            if (params.getTypes().contains(TYPE_DIAGRAM)) {
                shareDiagramIds = this.getShareDiagramIds();
            }
        }

        //资产管理
        Map<Long, ESCIClassInfo> ciClassInfoMap = new ConcurrentHashMap<>();
        Map<String, AppSquareConfig> appSquareConfigMap = new ConcurrentHashMap<>();
        Map<String, ESCIInfo> privateCiInfoMap = new ConcurrentHashMap<>();
        Map<String, ESCIInfo> designCiInfoMap = new ConcurrentHashMap<>();
        Map<Long, List<String>> classDefWithLabels = new HashMap<>();
        if (params.getTypes().contains(TYPE_ASSET) &&
                params.getLocationTypes().contains(GlobalSearchLocationType.ASSET_MANAGE)) {
            //资产配置所有分类信息
            List<ESCIClassInfo> assetCIClass = this.getAssetCIClass();
            ciClassInfoMap = assetCIClass.stream().collect(Collectors.toMap(ESCIClassInfo::getId, e -> e));
            //资产管理卡片信息
            List<AppSquareConfig> appSquareConfigs = this.getAssetAppSquareConf();
            appSquareConfigMap = appSquareConfigs.stream().collect(Collectors.toMap(AppSquareConfig::getClassCode, e -> e, (k1,k2) -> k1));
            //ci属性转换
            Map<LibType, List<GlobalSearchResVo>> assetGroupByLibType = datas.stream()
                    .filter(data -> data.getType().equals(TYPE_ASSET))
                    .collect(Collectors.groupingBy(GlobalSearchResVo::getLibType));
            if (assetGroupByLibType.containsKey(LibType.PRIVATE)) {
                List<ESCIInfo> privateCIInfos = assetGroupByLibType.get(LibType.PRIVATE)
                        .stream().map(GlobalSearchResVo::getCiInfo).collect(Collectors.toList());
                esciPrivateSvc.transCIAttrs(privateCIInfos, true);
                privateCiInfoMap = privateCIInfos.stream().collect(Collectors.toMap(ESCIInfo::getCiCode, e -> e, (k1,k2) -> k1));
            }
            if (assetGroupByLibType.containsKey(LibType.DESIGN)) {
                List<ESCIInfo> designCIInfos = assetGroupByLibType.get(LibType.DESIGN)
                        .stream().map(GlobalSearchResVo::getCiInfo).collect(Collectors.toList());
                esciDesignSvc.transCIAttrs(designCIInfos, true);
                designCiInfoMap = designCIInfos.stream().collect(Collectors.toMap(ESCIInfo::getCiCode, e -> e, (k1,k2) -> k1));
            }
            //分类属性label字段
            List<Long> ciClassIds = assetCIClass.stream().map(ESCIClassInfo::getId).collect(Collectors.toList());
            List<ESCIClassInfo> classInfos = classSvc.getTargetAttrDefsByClassIds(SysUtil.getCurrentUserInfo().getDomainId(), ciClassIds);
            if (!CollectionUtils.isEmpty(classInfos)) {
                for (ESCIClassInfo classInfo : classInfos) {
                    for (CcCiAttrDef def : classInfo.getAttrDefs()) {
                        if (def.getIsCiDisp() > 0) {
                            List<String> defWithLabels = classDefWithLabels.getOrDefault(classInfo.getId(), new ArrayList<>());
                            defWithLabels.add(def.getProName());
                            classDefWithLabels.put(classInfo.getId(), defWithLabels);
                        }
                    }
                }
            }
        }

        return GlobalSearchCategoryFillParam.builder()
                .privateCategoryMap(privateCategoryMap)
                .designCategoryMap(designCategoryMap)
                .shareDiagramIds(shareDiagramIds)
                .sharePlanIds(sharePlanIds)
                .libraryModuleMap(libraryModuleMap)
                .designModule(designModule)
                .userInfoMap(userInfoMap)
                .ciClassInfoMap(ciClassInfoMap)
                .appSquareConfigMap(appSquareConfigMap)
                .privateCiInfoMap(privateCiInfoMap)
                .designCiInfoMap(designCiInfoMap)
                .classDefWithLabels(classDefWithLabels)
                .build();
    }

    private Map<Long, List<AssetWarehouseDir>> libraryModuleMap(List<AssetWarehouseDir> sysModules) {
        Map<Long, List<AssetWarehouseDir>> libraryModuleMap = new ConcurrentHashMap<>();
        //资产分库目录
        List<EamCategoryDTO> libraries = eamCategorySvc.queryDesignPermissionRootList(SysUtil.getCurrentUserInfo().getLoginCode());
        if (CollectionUtils.isEmpty(libraries)) {
            return libraryModuleMap;
        }

        List<AssetWarehouseDir> groupsAndLibraries = sysModules.stream()
                .filter(sysModule -> sysModule.getModuleType() != null)
                .filter(sysModule -> sysModule.getModuleType() == 2 || sysModule.getModuleType() == 3)
                .collect(Collectors.toList());
        if (CollectionUtils.isEmpty(groupsAndLibraries)) {
            return libraryModuleMap;
        }
        Map<Long, AssetWarehouseDir> sysModuleMap = groupsAndLibraries.stream().collect(Collectors.toMap(AssetWarehouseDir::getId, each -> each, (k1, k2) -> k2));
        for (EamCategoryDTO library : libraries) {
            AssetWarehouseDir sysModule = library.getSysModulel();
            if (sysModule.getId().equals(sysModule.getParentId())) {
                continue;
            }
            List<AssetWarehouseDir> parentModules = this.getParentModules(new ArrayList<>(), sysModule.getParentId(), sysModuleMap);
            parentModules.add(sysModule);
            libraryModuleMap.put(library.getId(), parentModules);
        }
        return libraryModuleMap;
    }

    private List<AssetWarehouseDir> getParentModules(List<AssetWarehouseDir> parentSysModules, Long parentId, Map<Long, AssetWarehouseDir> sysModuleMap) {
        if (!sysModuleMap.containsKey(parentId)) {
            return parentSysModules;
        }
        AssetWarehouseDir parentSysModule = sysModuleMap.get(parentId);
        parentSysModules.add(parentSysModule);
        parentId = parentSysModule.getParentId();
        return this.getParentModules(parentSysModules, parentId, sysModuleMap);
    }

    private Map<Long, EamCategory> getCategoryMapByDirIds(List<Long> dirIds, LibType libType) {
        if (CollectionUtils.isEmpty(dirIds)) {
            return new ConcurrentHashMap<>();
        }
        List<EamCategory> categories = eamCategorySvc.getByIds(dirIds, libType);
        if (CollectionUtils.isEmpty(categories)) {
            return new ConcurrentHashMap<>();
        }
        Set<Long> dirPathIds = new HashSet<>();
        for (EamCategory category : categories) {
            if (StringUtils.isBlank(category.getDirPath())) {
                continue;
            }
            String dirPath = category.getDirPath().substring(1, category.getDirPath().length() - 1);
            String[] pathIds = dirPath.split("#");
            for (String pathId : pathIds) {
                dirPathIds.add(Long.valueOf(pathId));
            }
        }
        categories = eamCategorySvc.getByIds(new ArrayList<>(dirPathIds), libType);
        return categories.stream().collect(Collectors.toMap(EamCategory::getId, e -> e));
    }

    private void fillCategory(GlobalSearchResVo data, GlobalSearchCategoryFillParam fillParam) {
        if (data.getDirId() == null) {
            return;
        }
        //处理下分享-根目录维护为："我的空间"-"与我协作"
        if (fillParam.getShareDiagramIds().contains(data.getId())
                || fillParam.getSharePlanIds().contains(data.getId())) {
            List<GlobalSearchResDirVo> dirPaths = new ArrayList<>();
            dirPaths.add(new GlobalSearchResDirVo(0L, "我的空间"));
            dirPaths.add(new GlobalSearchResDirVo(2L, "与我协作"));
            data.setDirId(2L);
            data.setDirPath(dirPaths);
            return;
        }
        //处理下资产根目录为"我的空间"的情况
        if (data.getLibType() == LibType.PRIVATE && data.getDirId() == 0L) {
            List<GlobalSearchResDirVo> dirPaths = new ArrayList<>();
            dirPaths.add(new GlobalSearchResDirVo(0L, "我的空间"));
            data.setDirPath(dirPaths);
            return;
        }
        Map<Long, EamCategory> categoryMap = data.getLibType() == LibType.PRIVATE ?
                fillParam.getPrivateCategoryMap() : fillParam.getDesignCategoryMap();
        EamCategory category = categoryMap.getOrDefault(data.getDirId(), new EamCategory());
        if (StringUtils.isBlank(category.getDirPath())) {
            return;
        }
        List<GlobalSearchResDirVo> dirPaths = new ArrayList<>();
        //"我的空间"根目录后端不维护且私有库目录dirpath不维护根目录id，所以私有库资产路径需要维护个根目录
        if (data.getLibType() == LibType.PRIVATE) {
            dirPaths.add(new GlobalSearchResDirVo(0L, "我的空间"));
        }
        String path = category.getDirPath().substring(1, category.getDirPath().length() - 1);
        String[] pathIds = path.split("#");
        Long rootId = Long.valueOf(pathIds[0]);
        //"资产仓库"维护菜单路径
        if (data.getLibType() == LibType.DESIGN && fillParam.getLibraryModuleMap().containsKey(rootId)) {
            //返回结果维护根目录id方便前端跳转
            data.setRootId(rootId);
            //维护"资产仓库"菜单
            dirPaths.add(new GlobalSearchResDirVo(fillParam.getDesignModule().getId(), fillParam.getDesignModule().getLabel()));
            List<AssetWarehouseDir> sysModules = fillParam.getLibraryModuleMap().get(rootId);
            for (AssetWarehouseDir sysModule : sysModules) {
                dirPaths.add(new GlobalSearchResDirVo(sysModule.getId(), sysModule.getName()));
            }
        }
        for (String pathId : pathIds) {
            Long id = Long.valueOf(pathId);
            //模型数据不显示自己
            if (data.getId().equals(id)) {
                continue;
            }
            dirPaths.add(new GlobalSearchResDirVo(id, categoryMap.getOrDefault(id, new EamCategory()).getDirName()));
        }
        data.setDirPath(dirPaths);
    }

    private void fillAssetInfo(GlobalSearchResVo data, GlobalSearchCategoryFillParam fillParam) {
        if (!data.getType().equals(TYPE_ASSET)) {
            return;
        }
        ESCIInfo ciInfo = data.getCiInfo();
        Long ciClassId = ciInfo.getClassId();
        String ciClassCode = fillParam.getCiClassInfoMap().get(ciClassId).getClassCode();
        List<String> defLabels = fillParam.getClassDefWithLabels().getOrDefault(ciClassId, new ArrayList<>());
        data.setStatus(ciInfo.getAttrs().get("资产状态") == null ? "-" : ciInfo.getAttrs().get("资产状态").toString());
        String name = "";
        for (String deflabel : defLabels) {
            if (ciInfo.getAttrs().get(deflabel) == null) {
                continue;
            }
            String n = ciInfo.getAttrs().get(deflabel).toString();
            if (StringUtils.isNotBlank(n)) {
                name = n;
                break;
            }
        }
        data.setName(name);
        data.setClassCode(ciClassCode);
        //位置
        List<GlobalSearchResDirVo> dirPaths = new ArrayList<>();
        dirPaths.add(new GlobalSearchResDirVo(0L, "资产管理"));
        //卡片
        AppSquareConfig appSquareConfig = fillParam.getAppSquareConfigMap().get(ciClassCode);
        dirPaths.add(new GlobalSearchResDirVo(appSquareConfig.getId(), appSquareConfig.getCardName()));
        data.setDirPath(dirPaths);
        data.setCiInfo(null);
        data.setAppSquareConfId(appSquareConfig.getId());
    }

    /**
     * 结果转换
     * @param pageNum
     * @param pageSize
     * @param totalCount
     * @param datas
     * @return
     */
    private Page<GlobalSearchResVo> resultTransPage(long pageNum, long pageSize, long totalCount, List<GlobalSearchResVo> datas) {
        Page<GlobalSearchResVo> page = new Page<>();
        page.setPageNum(pageNum);
        page.setPageSize(pageSize);
        if (totalCount == 0) {
            page.setTotalRows(totalCount);
            page.setTotalPages(1);
            page.setData(datas);
            return page;
        }
        long totalPages = totalCount % pageSize;
        if (totalPages == 0) {
            page.setTotalPages(totalCount / pageSize);
        } else {
            page.setTotalPages(totalCount / pageSize + 1);
        }
        page.setTotalRows(totalCount);
        page.setData(datas);
        return page;
    }

    private BoolQueryBuilder getQueryBuilder(GlobalSearchQueryVo params) {
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        UserInfo user = userApiSvc.getUserInfoById(SysUtil.getCurrentUserInfo().getId());
        List<SysModule> sysModules = esModuleSvc.getListByRoleIds(
                user.getRoles().stream().map(SysRole::getId).collect(Collectors.toList()));
        //无菜单权限查空
        if (CollectionUtils.isEmpty(sysModules) || shouldJump(params)) {
            return emptyQuery();
        }
        if (params.getLocationTypes().contains(GlobalSearchLocationType.PRIVATE) && needQuery(params)) {
            query.should(this.getPrivateQuery(params, sysModules));
        }
        if (params.getLocationTypes().contains(GlobalSearchLocationType.DESIGN) && needQuery(params)) {
            query.should(this.getDesignQuery(params));
        }
        if (params.getLocationTypes().contains(GlobalSearchLocationType.ASSET_MANAGE)
                && params.getTypes().contains(TYPE_ASSET)) {
            query.should(this.getAssetManageQuery(params));
        }
        return query;
    }

    private boolean shouldJump(GlobalSearchQueryVo params) {
        //类型只有"资产"且位置不包含"资产管理"时，本次查询跳过。
        boolean onlyAssetTypeNotHasAssetLocation = !params.getLocationTypes().contains(GlobalSearchLocationType.ASSET_MANAGE)
                && params.getTypes().size() == 1
                && params.getTypes().contains(TYPE_ASSET);
        //位置只有"资产管理"且类型不包含"资产"时，本次查询跳过。
        boolean onlyAssetLocationNotHasAssetType = !params.getTypes().contains(TYPE_ASSET)
                && params.getLocationTypes().size() == 1
                && params.getLocationTypes().contains(GlobalSearchLocationType.ASSET_MANAGE);
        return onlyAssetTypeNotHasAssetLocation || onlyAssetLocationNotHasAssetType;
    }

    private boolean needQuery(GlobalSearchQueryVo params) {
        return params.getTypes().contains(TYPE_PLAN)
                || params.getTypes().contains(TYPE_DIAGRAM)
                || params.getTypes().contains(TYPE_MODEL);
    }

    /**
     * 私有库查询条件
     * @param params
     * @param sysModules
     * @return
     */
    private BoolQueryBuilder getPrivateQuery(GlobalSearchQueryVo params, List<SysModule> sysModules) {
        BoolQueryBuilder privateQuery = QueryBuilders.boolQuery();
        //"我的空间"菜单权限
        List<SysModule> frameworkDesigns = sysModules.stream().filter(sysModule ->
                sysModule.getModuleUrl() != null && sysModule.getModuleUrl().contains(MY_DESIGN_ROUTE_KEYS)).collect(Collectors.toList());
        //无权限查空
        if (CollectionUtils.isEmpty(frameworkDesigns)) {
            return emptyQuery();
        }
        //"我的空间"目录列表
        List<EamCategoryDTO> categories = eamCategorySvc.queryList(LibType.PRIVATE, 0L);
        //兼容数据在根目录下的情况
        EamCategoryDTO root = new EamCategoryDTO();
        root.setId(0L);
        categories.add(root);
        if (params.getTypes().contains(TYPE_PLAN)) {
            privateQuery.should(this.getPlanPrivateQuery(params, categories));
        }
        if (params.getTypes().contains(TYPE_DIAGRAM)) {
            privateQuery.should(this.getDiagramPrivateQuery(params, categories));
        }
        if (params.getTypes().contains(TYPE_MODEL)) {
            privateQuery.should(this.getModelPrivateQuery(params));
        }
        return privateQuery;
    }

    /**
     * 资产库查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getDesignQuery(GlobalSearchQueryVo params) {
        BoolQueryBuilder designQuery = QueryBuilders.boolQuery();
        //资产分库目录
        List<EamCategoryDTO> libraries = eamCategorySvc.queryDesignPermissionRootList(SysUtil.getCurrentUserInfo().getLoginCode());
        //无权限查空
        if (CollectionUtils.isEmpty(libraries)) {
            return emptyQuery();
        }
        boolean hasTypeModel = false;
        boolean hasTypePlan = false;
        boolean hasTypeDiagram = false;
        if (params.getTypes().contains(TYPE_MODEL)) {
            designQuery.should(this.getModelDesignQuery(params, libraries));
            hasTypeModel = true;
        }
        //获取拥有目录查看权限且文件查看权限的目录
        List<EamCategoryDTO> categories = eamCategorySvc.queryChildsWithFileReadPemissonByParentIds(libraries.stream().map(
                EamCategoryDTO::getId).collect(Collectors.toList()), LibType.DESIGN);
        Set<Long> categoryIds = categories.stream().map(EamCategoryDTO::getId).collect(Collectors.toSet());
        if (params.getTypes().contains(TYPE_PLAN)) {
            if (!CollectionUtils.isEmpty(categoryIds)) {
                designQuery.should(this.getPlanDesignQuery(params, categoryIds));
                hasTypePlan = true;
            }
        }
        if (params.getTypes().contains(TYPE_DIAGRAM)) {
            if (!CollectionUtils.isEmpty(categoryIds)) {
                designQuery.should(this.getDiagramDesignQuery(params, categoryIds));
                hasTypeDiagram = true;
            }
        }
        //满足任一条件，返回designQuery
        if (hasTypeModel || hasTypePlan || hasTypeDiagram) {
            return designQuery;
        }
        return emptyQuery();
    }

    /**
     * 资产管理查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getAssetManageQuery(GlobalSearchQueryVo params) {
        List<ESCIClassInfo> ciClasses = this.getAssetCIClass();
        if (CollectionUtils.isEmpty(ciClasses)) {
            return emptyQuery();
        }
        Set<Long> ciClassIds = ciClasses.stream().map(ESCIClassInfo::getId).collect(Collectors.toSet());
        return getCIQueryBuildByLabels(ciClassIds, params.getKeyword());
    }

    /**
     * 获取资产配置的所有分类信息
     * @return
     */
    private List<ESCIClassInfo> getAssetCIClass() {
        //获取资产卡片信息
        List<AppSquareConfig> appSquareConfigs = this.getAssetAppSquareConf();
        if (CollectionUtils.isEmpty(appSquareConfigs)) {
            return new ArrayList<>();
        }
        Set<String> ciClassCodes = appSquareConfigs.stream()
                .map(AppSquareConfig::getClassCode)
                .filter(StringUtils::isNotBlank).collect(Collectors.toSet());
        if (CollectionUtils.isEmpty(ciClassCodes)) {
            return new ArrayList<>();
        }
        //获取分类定义及分类属性定义
        BoolQueryBuilder ciClassCodesQuery = QueryBuilders.boolQuery();
        ciClassCodesQuery.must(QueryBuilders.termsQuery("classCode.keyword", ciClassCodes));
        return classSvc.getListByQuery(ciClassCodesQuery);
    }

    /**
     * 获取所有资产卡片
     * @return
     */
    private List<AppSquareConfig> getAssetAppSquareConf() {
        AppSquareConfigBo basicSettingBo = new AppSquareConfigBo();
        basicSettingBo.setClassification("5");
        return basicOperationSettingSvc.getListInfo(basicSettingBo);
    }

    private BoolQueryBuilder emptyQuery() {
        BoolQueryBuilder emptyQuery = QueryBuilders.boolQuery();
        return emptyQuery.must(QueryBuilders.termQuery("id", -1));
    }

    private BoolQueryBuilder getCIQueryBuildByLabels(Set<Long> ciClassIds, String keyword) {
        SysUser currentUser = SysUtil.getCurrentUserInfo();
        //获取实际的属性值
        List<ESCIClassInfo> classInfos = classSvc.getTargetAttrDefsByClassIds(currentUser.getDomainId(), ciClassIds);
        if (CollectionUtils.isEmpty(classInfos)) {
            return emptyQuery();
        }
        Map<Long, List<String>> classDefWithLabels = new HashMap<>();
        for (ESCIClassInfo classInfo : classInfos) {
            for (CcCiAttrDef def : classInfo.getAttrDefs()) {
                if (def.getIsCiDisp() > 0) {
                    List<String> defWithLabels = classDefWithLabels.getOrDefault(classInfo.getId(), new ArrayList<>());
                    defWithLabels.add(def.getProName());
                    classDefWithLabels.put(classInfo.getId(), defWithLabels);
                }
            }
        }
        if (CollectionUtils.isEmpty(classDefWithLabels)) {
            return emptyQuery();
        }
        BoolQueryBuilder ciAttrQuerys = QueryBuilders.boolQuery();
        for (Map.Entry<Long, List<String>> entry : classDefWithLabels.entrySet()) {
            List<ESAttrBean> orAttrs = new ArrayList<>();
            for (String attrName : entry.getValue()) {
                ESAttrBean attrBean = new ESAttrBean();
                attrBean.setOptType(2);
                attrBean.setKey(attrName);
                attrBean.setValue(keyword);
                orAttrs.add(attrBean);
            }
            //私有库ci查询
            ESCISearchBean privateBean = new ESCISearchBean();
            privateBean.setClassIds(Arrays.asList(entry.getKey()));
            privateBean.setOrAttrs(orAttrs);
            BoolQueryBuilder privateCiAttrQuery = (BoolQueryBuilder)commSvc.getCIQueryBuilderByBean(privateBean);
            privateCiAttrQuery.must(QueryBuilders.termQuery("ownerCode.keyword", currentUser.getLoginCode()));
            privateCiAttrQuery.must(QueryBuilders.termQuery("_index", getAssetEsPrivateIndex()));
            ciAttrQuerys.should(privateCiAttrQuery);
            //资产库ci查询
            ESCISearchBean designBean = new ESCISearchBean();
            designBean.setClassIds(Arrays.asList(entry.getKey()));
            designBean.setOrAttrs(orAttrs);
            BoolQueryBuilder designCiAttrQuery = (BoolQueryBuilder)commSvc.getCIQueryBuilderByBean(designBean);
            designCiAttrQuery.must(QueryBuilders.termQuery("_index", getAssetEsDesignIndex()));
            ciAttrQuerys.should(designCiAttrQuery);
        }
        return ciAttrQuerys;
    }

    /**
     * 视图私有仓库查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getDiagramPrivateQuery(GlobalSearchQueryVo params, List<EamCategoryDTO> categories) {
        BoolQueryBuilder diagramPrivateQuery = QueryBuilders.boolQuery();
        diagramPrivateQuery.must(this.getDiagramCommonQuery(params));

        BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
        if (!CollectionUtils.isEmpty(categories)) {
            //视图由我创建
            BoolQueryBuilder diagramCreateQuery = QueryBuilders.boolQuery();
            //是否公开:1=资产仓库 0=私有仓库
            diagramCreateQuery.must(QueryBuilders.termQuery(IS_OPEN, 0));
            //由我创建
            diagramCreateQuery.must(QueryBuilders.termQuery("creator.keyword", SysUtil.getCurrentUserInfo().getLoginCode()));
            diagramCreateQuery.must(QueryBuilders.termsQuery("dirId", categories.stream().map(EamCategoryDTO::getId).collect(Collectors.toSet())));
            shouldQuery.should(diagramCreateQuery);
        }
        //视图分享给我
        BoolQueryBuilder diagramShareQuery = QueryBuilders.boolQuery();
        diagramShareQuery.must(QueryBuilders.termsQuery("id", getShareDiagramIds()));
        diagramShareQuery.must(QueryBuilders.termQuery(IS_OPEN, 0));
        shouldQuery.should(diagramShareQuery);
        diagramPrivateQuery.must(shouldQuery);
        return diagramPrivateQuery;
    }

    /**
     * 视图资产仓库查询条件
     * @param params
     * @param categoryIds
     * @return
     */
    private BoolQueryBuilder getDiagramDesignQuery(GlobalSearchQueryVo params, Set<Long> categoryIds) {
        BoolQueryBuilder diagramDesignQuery = QueryBuilders.boolQuery();
        diagramDesignQuery.must(this.getDiagramCommonQuery(params));

        //是否公开:1=资产仓库 0=私有仓库
        diagramDesignQuery.must(QueryBuilders.termQuery(IS_OPEN, 1));
        //权限目录过滤
        diagramDesignQuery.must(QueryBuilders.termsQuery(DIRID, categoryIds));
        return diagramDesignQuery;
    }

    /**
     * 视图公共查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getDiagramCommonQuery(GlobalSearchQueryVo params) {
        BoolQueryBuilder diagramCommonQuery = QueryBuilders.boolQuery();
        //作用域
        diagramCommonQuery.must(QueryBuilders.termQuery(DOMAIN_ID_STRING, SysUtil.getCurrentUserInfo().getDomainId()));
        //名称模糊
        diagramCommonQuery.must(QueryBuilders.wildcardQuery("name.keyword", "*" + params.getKeyword() + "*"));
        //主线版本
        diagramCommonQuery.must(QueryBuilders.termQuery("historyVersionFlag", 1));
        //视图状态:1=正常 0=回收站
        diagramCommonQuery.must(QueryBuilders.termQuery(STATUS, 1));
        //数据状态:0=删除，1=正常
        diagramCommonQuery.must(QueryBuilders.termQuery("dataStatus", 1));
        //不查询模板类型的视图
        diagramCommonQuery.must(QueryBuilders.termsQuery("diagramType",Arrays.asList(1,2)));
        return diagramCommonQuery;
    }

    /**
     * 方案私有仓库查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getPlanPrivateQuery(GlobalSearchQueryVo params, List<EamCategoryDTO> categories) {
        BoolQueryBuilder planPrivateQuery = QueryBuilders.boolQuery();
        planPrivateQuery.must(this.getPlanCommonQuery(params));

        BoolQueryBuilder shouldQuery = QueryBuilders.boolQuery();
        if (!CollectionUtils.isEmpty(categories)) {
            //方案由我创建
            BoolQueryBuilder planCreateQuery = QueryBuilders.boolQuery();
            planCreateQuery.must(QueryBuilders.termQuery("creatorCode.keyword", SysUtil.getCurrentUserInfo().getLoginCode()));
            planCreateQuery.must(QueryBuilders.termsQuery("dirId", categories.stream().map(EamCategoryDTO::getId).collect(Collectors.toSet())));
            //资产类型：1:设计库 2:资产库
            planCreateQuery.must(QueryBuilders.termQuery(ASSETS_TYPE, 1));
            shouldQuery.should(planCreateQuery);
        }
        //方案分享给我
        BoolQueryBuilder planShareQuery = QueryBuilders.boolQuery();
        //分享
        planShareQuery.must(QueryBuilders.termsQuery("id", getSharePlanIds()));
        planShareQuery.must(QueryBuilders.termQuery(ASSETS_TYPE, 1));
        shouldQuery.should(planShareQuery);
        planPrivateQuery.must(shouldQuery);
        planPrivateQuery.must(QueryBuilders.termQuery("_index", getPlanEsIndex()));
        return planPrivateQuery;
    }

    /**
     * 方案资产仓库查询条件
     * @param params
     * @param categoryIds
     * @return
     */
    private BoolQueryBuilder getPlanDesignQuery(GlobalSearchQueryVo params, Set<Long> categoryIds) {
        BoolQueryBuilder planDesignQuery = QueryBuilders.boolQuery();
        planDesignQuery.must(this.getPlanCommonQuery(params));
        //资产类型：1:设计库 2:资产库
        planDesignQuery.must(QueryBuilders.termQuery(ASSETS_TYPE, 2));
        planDesignQuery.must(QueryBuilders.termsQuery("assetsDirId", categoryIds));
        return planDesignQuery;
    }

    /**
     * 方案公共查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getPlanCommonQuery(GlobalSearchQueryVo params) {
        BoolQueryBuilder planCommonQuery = QueryBuilders.boolQuery();
        //作用域
        planCommonQuery.must(QueryBuilders.termQuery(DOMAIN_ID_STRING, BaseConst.DEFAULT_DOMAIN_ID));
        //名称模糊
        planCommonQuery.must(QueryBuilders.wildcardQuery("name.keyword", "*" + params.getKeyword() + "*"));
        //非删除状态、非历史版本状态
        planCommonQuery.mustNot(QueryBuilders.termsQuery("status.keyword", "deleted","history"));
        return planCommonQuery;
    }

    /**
     * 模型私有库查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getModelPrivateQuery(GlobalSearchQueryVo params) {
        BoolQueryBuilder modelPrivateQuery = QueryBuilders.boolQuery();
        modelPrivateQuery.must(getModelCommonQuery(params));
        modelPrivateQuery.must(QueryBuilders.termQuery("_index", getModelEsPrivateIndex()));
        modelPrivateQuery.must(QueryBuilders.termQuery("ownerCode.keyword", SysUtil.getCurrentUserInfo().getLoginCode()));
        return modelPrivateQuery;
    }

    private BoolQueryBuilder getModelDesignQuery(GlobalSearchQueryVo params, List<EamCategoryDTO> libraries) {
        //获取拥有模型查看权限的子目录
        List<EamCategoryDTO> categoryDTOS = eamCategorySvc.queryChildsWithModelReadPemissonByParentIds(
                libraries.stream().map(EamCategoryDTO::getId).collect(Collectors.toList()), LibType.DESIGN);
        List<Long> categoryIds = categoryDTOS.stream().map(EamCategoryDTO::getId).collect(Collectors.toList());
        if (CollectionUtils.isEmpty(categoryDTOS)) {
            return emptyQuery();
        }
        BoolQueryBuilder modelDesignQuery = QueryBuilders.boolQuery();
        modelDesignQuery.must(getModelCommonQuery(params));
        modelDesignQuery.must(QueryBuilders.termQuery("_index", getModelEsDesignIndex()));
        modelDesignQuery.must(QueryBuilders.termsQuery("id", categoryIds));
        return modelDesignQuery;
    }

    /**
     * 模型公共查询条件
     * @param params
     * @return
     */
    private BoolQueryBuilder getModelCommonQuery(GlobalSearchQueryVo params) {
        BoolQueryBuilder modelCommonQuery = QueryBuilders.boolQuery();
        //作用域
        modelCommonQuery.must(QueryBuilders.termQuery(DOMAIN_ID_STRING, BaseConst.DEFAULT_DOMAIN_ID));
        //名称模糊
        modelCommonQuery.must(QueryBuilders.wildcardQuery("dirName.keyword", "*" + params.getKeyword() + "*"));
        //模型根目录
        modelCommonQuery.must(QueryBuilders.termQuery("type", CategoryTypeEnum.MODEL_ROOT.val()));
        modelCommonQuery.must(QueryBuilders.termQuery("dataStatus", 1));
        return modelCommonQuery;
    }

    private List<Long> getShareDiagramIds() {
        List<DiagramShareRecord> diagramShareRecords = shareDiagramSvc.queryByUserId(SysUtil.getCurrentUserInfo().getId());
        return diagramShareRecords.stream().map(DiagramShareRecord::getDiagramId).collect(Collectors.toList());
    }

    private List<Long> getSharePlanIds() {
        BoolQueryBuilder query = QueryBuilders.boolQuery();
        query.must(QueryBuilders.termQuery(STATUS, 1));
        query.must(QueryBuilders.termQuery("sharedLoginCode.keyword", SysUtil.getCurrentUserInfo().getLoginCode()));
        query.must(QueryBuilders.termQuery(DOMAIN_ID_STRING, SysUtil.getCurrentUserInfo().getDomainId()));
        List<PlanDesignShareRecord> planDesignShareRecords = planDesignShareRecordDao.getListByQuery(query);
        return planDesignShareRecords.stream().map(PlanDesignShareRecord::getPlanDesignId).distinct().collect(Collectors.toList());
    }

    private String getDiagramEsIndex() {
        return this.warpIndexAndType(ES_INDEX_DIAGRAM);
    }

    private String getDiagramEsType() {
        return this.warpIndexAndType(ES_TYPE_DIAGRAM);
    }

    private String getPlanEsIndex() {
        return this.warpIndexAndType(ES_INDEX_PLAN);
    }

    private String getPlanEsType() {
        return this.warpIndexAndType(ES_TYPE_PLAN);
    }

    private List<String> getAssetEsIndex() {
        return Arrays.asList(getAssetEsPrivateIndex(), getAssetEsDesignIndex());
    }

    private String getAssetEsPrivateIndex() {
        return this.warpIndexAndType(ES_INDEX_CI_PRIVATE);
    }

    private String getAssetEsDesignIndex() {
        return this.warpIndexAndType(ES_INDEX_CI_DESIGN);
    }

    private List<String> getAssetEsType() {
        return Arrays.asList(this.warpIndexAndType(ES_TYPE_CI_PRIVATE), this.warpIndexAndType(ES_TYPE_CI_DESIGN));
    }

    private List<String> getModelEsIndex(List<GlobalSearchLocationType> locationTypes) {
        List<String> esIndex = new ArrayList<>();
        if (locationTypes.contains(GlobalSearchLocationType.PRIVATE)) {
            esIndex.add(getModelEsPrivateIndex());
        }
        if (locationTypes.contains(GlobalSearchLocationType.DESIGN)) {
            esIndex.add(getModelEsDesignIndex());
        }
        return esIndex;
    }

    private String getModelEsPrivateIndex() {
        return this.warpIndexAndType(ES_INDEX_MODEL_PRIVATE);
    }

    private String getModelEsDesignIndex() {
        return this.warpIndexAndType(ES_INDEX_MODEL_DESIGN);
    }

    private List<String> getModelEsType(List<GlobalSearchLocationType> locationTypes) {
        List<String> esType = new ArrayList<>();
        if (locationTypes.contains(GlobalSearchLocationType.PRIVATE)) {
            esType.add(this.warpIndexAndType(ES_TYPE_MODEL_PRIVATE));
        }
        if (locationTypes.contains(GlobalSearchLocationType.DESIGN)) {
            esType.add(this.warpIndexAndType(ES_TYPE_MODEL_DESIGN));
        }
        return esType;
    }

    private String warpIndexAndType(String str) {
        return StringUtils.isBlank(dataScope) ? str : dataScope + "_" + str;
    }

    private String unWarpIndex(String index) {
        return StringUtils.isBlank(dataScope) ? index : index.replace(dataScope + "_", "");
    }

    private String transDateFormat(String date) {
        if (StringUtils.isBlank(date)) {
            return "-";
        }
        StringBuilder sb = new StringBuilder(date);
        while (sb.length() < 14) {
            sb.append("0");
        }
        String result = "-";
        try {
            SimpleDateFormat transDataF = new SimpleDateFormat("yyyyMMddHHmmss");
            Date trans = transDataF.parse(sb.toString());
            SimpleDateFormat df = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
            result = df.format(trans);
        } catch (ParseException e) {
            log.error("日期转换异常：{}", sb.toString());
        }
        return result;
    }
}
